﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using NeuralNetwork.Training;
using NeuralNetwork.OutputTypes;

namespace NeuralNetworkGUI
{
    public partial class frmImageTestSet : Form
    {
        private List<Output> outputs = null;
        private List<Test> tests = null;

        private Bitmap FixedSize(Image imgPhoto, int Width, int Height)
        {
            int sourceWidth = imgPhoto.Width;
            int sourceHeight = imgPhoto.Height;
            int sourceX = 0;
            int sourceY = 0;
            int destX = 0;
            int destY = 0;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = ((float)Width / (float)sourceWidth);
            nPercentH = ((float)Height / (float)sourceHeight);
            if (nPercentH < nPercentW)
            {
                nPercent = nPercentH;
                destX = System.Convert.ToInt16((Width -
                              (sourceWidth * nPercent)) / 2);
            }
            else
            {
                nPercent = nPercentW;
                destY = System.Convert.ToInt16((Height -
                              (sourceHeight * nPercent)) / 2);
            }

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
            bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.Clear(Color.Red);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;

            grPhoto.DrawImage(imgPhoto,
                              new Rectangle(destX, destY, destWidth, destHeight),
                              new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
                              GraphicsUnit.Pixel);

            grPhoto.Dispose();
            return bmPhoto;
        }

        public frmImageTestSet()
        {
            InitializeComponent();
        }

        public DialogResult ShowDialog(List<Test> tests, List<Output> outputs)
        {
            this.tests = tests;
            this.outputs = outputs;
            return this.ShowDialog();
        }

        private void btnDirectory_Click(object sender, EventArgs e)
        {
            if (fbdImageFolder.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = fbdImageFolder.SelectedPath;
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            btnLoadSet.Enabled = System.IO.Directory.Exists(textBox1.Text);
        }

        private bool ValidateOutput(string s)
        {
            foreach (Output o in outputs)
            {
                if (s == o.ToString()) return true;
            }
            return false;
        }

        private List<Output> MakeOutputList(Output value)
        {
            List<Output> ol = new List<Output>();
            foreach (Output o in outputs)
            {
                if (value.ToString() == o.ToString())
                    ol.Add(value);
                else
                    ol.Add(null);
            }
            return ol;
        }

        private void btnLoadSet_Click(object sender, EventArgs e)
        {
            if (System.IO.Directory.Exists(textBox1.Text) && 
                (tests != null) && (outputs != null))
            {
                // Determine maximum images size                
                Bitmap image = null;
                int width = -1;
                int height = -1;
                foreach (string f in Directory.GetFiles(textBox1.Text, "*.bmp"))
                {
                    image = new Bitmap(f);
                    if (width < image.Width) width = image.Width;
                    if (height < image.Height) height = image.Height;                    
                }
                
                // Clear existing set
                tests.Clear();

                // Make testsets
                string name = "";
                string output = "";
                List<Output> ol = null;
                foreach (string f in Directory.GetFiles(textBox1.Text, "*.bmp"))
                {
                    name = Path.GetFileName(f);
                    output = name.Substring(0, name.IndexOf("."));
                    if (ValidateOutput(output))
                    {
                        // Image
                        image = new Bitmap(f);
                        if ((image.Height != height) || (image.Width != width))
                        {
                            image = FixedSize(image, width, height);
                        }

                        // Output string
                        ol = MakeOutputList(new GenericOutput<string>(output));

                        // Add test set
                        tests.Add(new ImageTest(image, ol));
                    }
                }

                this.DialogResult = DialogResult.OK;
            }
            else
            {
                if (MessageBox.Show("Unable to load test set. Should the window be closed?", "Error loading image",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes)
                {
                    this.Close();
                }
            }
        }
    }
}
